/* * * * M A P V I S I O N   L I C E N S E  *****************************************************************
 *
 * This MapVision software is © Filip Zavadil 2013. It is licensed under the LGPL license.
 * This MapVision software dynamically links to unmodified Qt5 Library.
 *
 * The Qt5 Library is © 2013 Qt® and/or its subsidiary(-ies), and is licensed under the
 * GNU Lesser General Public License version 2.1 with Qt® LGPL exception version 1.1.
 * Qt5 library is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
 * Qt5 library is provided “AS IS”, without WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * As an additional permission to the GNU Lesser General Public License version 2.1, the object
 * code form of a “work that uses the Library” may incorporate material from a header file that is
 * part of the Library. You may distribute such object code under terms of your choice,
 * provided that: (i) the header files of the Library have not been modified; and (ii)
 * the incorporated material is limited to numerical parameters, data structure layouts, accessors,
 * macros, inline functions and templates; and (iii) you comply with the terms of Section 6 of the
 * GNU Lesser General Public License version 2.1.
 *
 * Moreover, you may apply this exception to a modified version of the Library, provided that such
 * modification does not involve copying material from the Library into the modified Library’s header
 * files unless such material is limited to (i) numerical parameters; (ii) data structure layouts;
 * (iii) accessors; and (iv) small macros, templates and inline functions of five lines or less in length.
 *
 * Furthermore, you are not required to apply this additional permission to a modified version of the Library.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this package;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

 * The source code for Qt 5.X SDK is available from Qt Project here:
 * http://download.qt-project.org/official_releases/qtcreator/2.7/2.7.0/qt-creator-2.7.0-src.zip.
 *
 * ****************************** M A P V I S I O N    S O F T W A R E  ************************************
 *
 * Author:       Filip Zavadil
 * Description:  Software for displaying and exporting map tiles.
 * The sources and executables of MapVision software are available:
 *    - from project hosting on CodePlex.com :   http://mapvision.codeplex.com
 *    - from GIT repositories on Gitorious.org:  https://gitorious.org/mapvision
 * Visit MapVision fanpage on Facebook.com:      https://www.facebook.com/pages/Mapvision/631827753513935
 *
 * *********************************************************************************************************
*/

#include "selectionrubberband.h"
#include <QMouseEvent>
#include <QGraphicsColorizeEffect>


SelectionRubberBand::SelectionRubberBand(QGraphicsView * view_ =0) : QRubberBand(Rectangle,view_)
{
    view=view_;

    this->setObjectName("selection");
    connect(view, SIGNAL(mouseMoved(QMouseEvent *)),this,SLOT(mouseMoved(QMouseEvent *)));
    connect(view, SIGNAL(mouseReleased(QMouseEvent *)),this,SLOT(mouseReleased(QMouseEvent *)));
    connect(view, SIGNAL(mousePressed(QMouseEvent *)),this,SLOT(mousePressed(QMouseEvent *)));
    connect(view, SIGNAL(zoomChanged(int)),this,SLOT(zoomChanged(int)));
    connect(view, SIGNAL(mapUpdated(QPointF,int,int)),this,SLOT(mapUpdated(QPointF,int,int)));
    connect(this, SIGNAL(sendMessage(QString)),view,SLOT(sendMessagePublic(QString)));

    active = false;
    zoom=1;
    dialog = new AddSelectionRect(view,this);

}

void SelectionRubberBand::isActive(bool active_)
{
    active = active_;

    if (!active)
    {
        this->hide();
        view->viewport()->setCursor(Qt::OpenHandCursor);
    }
    else
    {
        view->viewport()->setCursor(Qt::CrossCursor);
        this->setRectLonlat(rectLonlat);
        this->show();
    }
}

void SelectionRubberBand::setRectLonlat(QRectF rectLonlat_)
{
    rectLonlat = rectLonlat_;
    QRectF rect(view->mapFromScene(zavaProj.lonlat2pixels(rectLonlat_.topLeft(),zoom)),view->mapFromScene(zavaProj.lonlat2pixels(rectLonlat_.bottomRight(),zoom)));

    this->setGeometry(rect.toRect());
    emit selectionChanged(rectLonlat);

}

QRect SelectionRubberBand::getRectPixels(int zoom_)
{
    return QRect(zavaProj.lonlat2pixels(rectLonlat.topLeft(),zoom_),zavaProj.lonlat2pixels(rectLonlat.bottomRight(),zoom_));
}

QRect SelectionRubberBand::getRectTiles(int zoom_, ZavaProj::Yaxis yAxis)
{
    return QRect(zavaProj.lonlat2tileFormat(rectLonlat.topLeft(),zoom_,yAxis),zavaProj.lonlat2tileFormat(rectLonlat.bottomRight(),zoom_,yAxis));
}

void SelectionRubberBand::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter;
    QPen pen = QPen(Qt::white);
    pen.setWidth(2);


    QBrush brush = QBrush(Qt::red);

    painter.begin(this);
    painter.setPen(pen);
    painter.setOpacity(0.4);
    painter.setBrush(brush);
    painter.drawRect(event->rect());
    painter.end();
}

void SelectionRubberBand::showDialog()
{
    dialog->showDialog(0,"Select by rectangle");

}

void SelectionRubberBand::showInfo()
{
    dialog->showDialog(1,"Selection info");
}

void SelectionRubberBand::mousePressed(QMouseEvent * event)
{
    if (active && event->buttons() == Qt::LeftButton && view->viewport()->cursor().shape() != Qt::OpenHandCursor){
        origin = event->pos();
        this->show();
        rectLonlat=QRectF(zavaProj.pixels2lonlat(view->mapToScene(origin).toPoint(),zoom),QSize());
        this->setRectLonlat(rectLonlat);
        firstPoint = zavaProj.pixels2lonlat(view->mapToScene(origin).toPoint(),zoom);
    }
    button = event->button();

}

void SelectionRubberBand::mouseMoved(QMouseEvent * event)
{
    if (active && event->buttons() == Qt::LeftButton && view->viewport()->cursor().shape() != Qt::ClosedHandCursor){
        QPointF thisPoint = zavaProj.pixels2lonlat(view->mapToScene(event->pos()).toPoint(),zoom);

        if (thisPoint.x() > firstPoint.x() && firstPoint.y() > thisPoint.y()){
            rectLonlat= QRectF(firstPoint,thisPoint);

        } else if (thisPoint.x() < firstPoint.x() && firstPoint.y() < thisPoint.y()){
            rectLonlat= QRectF(thisPoint,firstPoint);
        }else if (thisPoint.x() < firstPoint.x() && firstPoint.y() > thisPoint.y()){
            rectLonlat.setTopRight(firstPoint);
            rectLonlat.setBottomLeft(thisPoint);
        } else if (thisPoint.x() > firstPoint.x() && firstPoint.y() < thisPoint.y()){
            rectLonlat.setTopRight(thisPoint);
            rectLonlat.setBottomLeft(firstPoint);
        }

        this->setRectLonlat(rectLonlat);
     view->update();
    }

}

void SelectionRubberBand::mouseReleased(QMouseEvent * event)
{
    if (active && event->buttons() == Qt::LeftButton && view->viewport()->cursor().shape() != Qt::OpenHandCursor){
        rectLonlat.setBottomRight(zavaProj.pixels2lonlat(view->mapToScene(event->pos()).toPoint(),zoom));
        button = Qt::NoButton;
        emit selectionChanged(rectLonlat);
    }
    else if (active && (button == Qt::MidButton || button == Qt::MiddleButton)){
    }
}

void SelectionRubberBand::zoomChanged(int zoom_)
{
    zoom = zoom_;
    this->setRectLonlat(rectLonlat);
}

void SelectionRubberBand::mapUpdated(QPointF centerPoint, int zoom , int scale)
{
    Q_UNUSED(centerPoint)
    Q_UNUSED(zoom)
    Q_UNUSED(scale)
    if (active)
    {
        this->setRectLonlat(rectLonlat);
    }
}





